<template>
    <div class="nr-page">
        <!-- 查询区域 -->
        <el-card shadow="never" class="search-card">
            <el-form :inline="true" :model="query" label-width="80px" class="search-form">
                <el-form-item label="目标表单">
                    <el-select v-model="query.targetName" placeholder="请选择" clearable style="width: 180px">
                        <el-option v-for="item in targetOptions" :key="item" :label="item" :value="item" />
                    </el-select>
                </el-form-item>
                <el-form-item label="编号前缀">
                    <el-input v-model.trim="query.prefix" placeholder="请输入单位名称/编号" clearable style="width: 180px" />
                </el-form-item>
                <el-form-item label="时间规则">
                    <el-input v-model.trim="query.timeRule" placeholder="请输入" clearable style="width: 180px" />
                </el-form-item>
                <el-form-item label="操作时间">
                    <el-date-picker v-model="query.operateTime" type="daterange" range-separator="至"
                        start-placeholder="开始日期" end-placeholder="结束日期" value-format="YYYY-MM-DD" clearable
                        style="width: 240px" />
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" @click="loadData()">查询</el-button>
                    <el-button @click="resetQuery">重置</el-button>
                </el-form-item>
            </el-form>
        </el-card>

        <!-- 操作按钮区域 -->
        <el-card shadow="never" class="action-card">
            <el-button type="success" @click="openEdit()">新增</el-button>
            <el-button type="primary" @click="handleExport">导出</el-button>
        </el-card>

        <!-- 表格区域 -->
        <el-card shadow="never" class="table-card">
            <el-table :data="rows" border stripe v-loading="loading" height="560px">
                <el-table-column type="index" label="序号" width="80" />
                <el-table-column prop="targetName" label="目标表单" min-width="140" show-overflow-tooltip />
                <el-table-column prop="codePrefix" label="编号前缀" width="120" />
                <el-table-column label="时间规则" min-width="160" show-overflow-tooltip>
                    <template #default="{ row }">
                        {{ formatTimeRuleToChinese(row.timeRule) }}
                    </template>
                </el-table-column>
                <el-table-column label="流水号/位" width="100">
                    <template #default="{ row }">
                        {{ row.serialLength }}
                    </template>
                </el-table-column>
                <el-table-column prop="step" label="步长" width="80" />
                <el-table-column prop="numberingExpression" label="编号生成规则" min-width="240" show-overflow-tooltip>
                    <template #default="{ row }">
                        {{ row.numberingExpression || buildPreview(row) }}
                    </template>
                </el-table-column>
                <el-table-column prop="createor" label="操作人" width="120" />
                <el-table-column label="操作时间" width="180">
                    <template #default="{ row }">
                        {{ formatDateTime(row.createrTime || row.updateTime) }}
                    </template>
                </el-table-column>
                <el-table-column label="操作" width="160" fixed="right">
                    <template #default="{ row }">
                        <el-button type="primary" link @click="openEdit(row)">编辑</el-button>
                        <el-divider direction="vertical" />
                        <el-popconfirm title="确认删除该规则？" @confirm="doRemove(row)">
                            <template #reference>
                                <el-button type="danger" link>删除</el-button>
                            </template>
                        </el-popconfirm>
                    </template>
                </el-table-column>
            </el-table>
        </el-card>

        <el-drawer v-model="editVisible" :title="form.ruleId ? '编辑规则' : '新增规则'" size="520px">
            <el-form :model="form" :rules="rules" ref="formRef" label-width="100px">
                <el-form-item label="目标表单" prop="targetName">
                    <el-input v-model.trim="form.targetName" placeholder="请输入目标表单" />
                </el-form-item>
                <el-form-item label="表单编码" prop="targetCode">
                    <el-input v-model.trim="form.targetCode" maxlength="30" placeholder="例如: Product" />
                </el-form-item>
                <el-form-item label="编码缩写" prop="codePrefix">
                    <el-input v-model.trim="form.codePrefix" maxlength="10" placeholder="例如 HP" />
                </el-form-item>
                <el-form-item label="时间规则 *" prop="timeRule">
                    <el-checkbox-group v-model="timeSegments">
                        <el-checkbox label="YYYY">年YYYY</el-checkbox>
                        <el-checkbox label="MM">月MM</el-checkbox>
                        <el-checkbox label="DD">日DD</el-checkbox>
                        <el-checkbox label="HH">时HH</el-checkbox>
                        <el-checkbox label="MI">分MM</el-checkbox>
                        <el-checkbox label="SS">秒SS</el-checkbox>
                    </el-checkbox-group>
                </el-form-item>
                <el-form-item label="流水号/位 *" prop="serialLength">
                    <el-input-number v-model="form.serialLength" :min="1" :max="10" />
                </el-form-item>
                <el-form-item label="步长" prop="step">
                    <el-input-number v-model="form.step" :min="1" :max="99" />
                </el-form-item>
                <el-form-item label="备注">
                    <el-input v-model.trim="form.remark" type="textarea" rows="2" maxlength="100" />
                </el-form-item>
                <el-form-item label="示例">
                    <el-input v-model="preview" readonly />
                </el-form-item>
            </el-form>
            <template #footer>
                <div class="drawer-footer">
                    <el-button @click="editVisible = false">取消</el-button>
                    <el-button type="primary" @click="doSave">保存</el-button>
                </div>
            </template>
        </el-drawer>
    </div>
</template>

<script setup lang="ts">
import { ref, reactive, computed, onMounted, watch, nextTick } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import type { FormInstance, FormRules } from 'element-plus'
import myaxios from '@/http/MyAxios'
import moment from 'moment'

type NumberRule = {
    ruleId?: string | number
    targetName: string
    targetCode: string
    codePrefix: string
    timeRule: string
    timeFormat?: string
    serialLength: number
    step: number
    remark?: string
    separator?: string
    operator?: string
    updater?: string
    creator?: string
    numberingExpression?: string
    updatedAt?: string
}

const defaultForm: NumberRule = {
    targetName: '',
    targetCode: '',
    codePrefix: '',
    timeRule: '',
    timeFormat: '',
    serialLength: 3,
    step: 1,
    remark: '',
    numberingExpression: '',
    creator: '',
    operator: '',
    updater: ''
}
const targetOptions = ref<string[]>([])

const query = reactive({
    targetName: '',
    prefix: '',
    timeRule: '',
    operateTime: null as [string, string] | null
})

const rows = ref<NumberRule[]>([])
const loading = ref(false)

const editVisible = ref(false)
const formRef = ref<FormInstance>()
const form = reactive<NumberRule>({ ...defaultForm })

const rules: FormRules<NumberRule> = {
    targetName: [{ required: true, message: '请输入目标表单', trigger: 'blur' }],
    targetCode: [{ required: true, message: '请输入表单编码', trigger: 'blur' }],
    codePrefix: [{ required: true, message: '请输入编码缩写', trigger: 'blur' }],
    timeRule: [{ required: true, message: '请至少选择一个时间规则', trigger: 'change' }],
    serialLength: [{ required: true, type: 'number', message: '请输入位数', trigger: 'change' }],
    step: [{ required: true, type: 'number', message: '请输入步长', trigger: 'change' }]
}

const timeSegments = ref<string[]>([])

watch(timeSegments, (val) => {
    form.timeRule = (val && val.length > 0) ? val.join(',') : ''
    // 触发时间规则的验证
    formRef.value?.validateField('timeRule')
}, { immediate: false })

const preview = computed(() => buildPreview(form))

function formatTimeRule(rule?: string) {
    if (!rule) return '无'
    return rule.replace(/,/g, ' / ')
}

// 将时间规则转换为中文描述（如：YYYY,MM,DD -> 年月日），按照从大到小顺序排列
function formatTimeRuleToChinese(rule?: string) {
    if (!rule) return '无'
    const map: Record<string, string> = {
        'YYYY': '年',
        'YY': '年',
        'MM': '月',
        'DD': '日',
        'HH': '时',
        'MI': '分',
        'SS': '秒'
    }
    // 定义时间单位的顺序（从大到小）
    const order: string[] = ['YYYY', 'YY', 'MM', 'DD', 'HH', 'MI', 'SS']
    const segments = rule.split(',').filter(Boolean).map(s => s.trim().toUpperCase())

    // 按照预定义顺序排序
    const sortedSegments = segments.sort((a, b) => {
        const indexA = order.indexOf(a)
        const indexB = order.indexOf(b)
        // 如果找不到，放到最后
        if (indexA === -1 && indexB === -1) return 0
        if (indexA === -1) return 1
        if (indexB === -1) return -1
        return indexA - indexB
    })

    return sortedSegments.map(seg => map[seg] || seg).join('') || rule
}

function buildPreview(r: Partial<NumberRule>) {
    const now = new Date()
    const segs = (r.timeRule || '').split(',').filter(Boolean).map(s => s.trim().toUpperCase())

    // 定义时间单位的顺序（从大到小）
    const order: string[] = ['YYYY', 'YY', 'MM', 'DD', 'HH', 'MI', 'SS']

    // 按照从大到小的顺序排序
    const sortedSegs = segs.sort((a, b) => {
        const indexA = order.indexOf(a)
        const indexB = order.indexOf(b)
        if (indexA === -1 && indexB === -1) return 0
        if (indexA === -1) return 1
        if (indexB === -1) return -1
        return indexA - indexB
    })

    const parts: string[] = []
    const pad = (n: number, len = 2) => `${n}`.padStart(len, '0')
    sortedSegs.forEach(s => {
        switch (s) {
            case 'YYYY':
                parts.push(String(now.getFullYear()))
                break
            case 'YY':
                parts.push(String(now.getFullYear()).slice(-2))
                break
            case 'MM':
                parts.push(pad(now.getMonth() + 1))
                break
            case 'DD':
                parts.push(pad(now.getDate()))
                break
            case 'HH':
                parts.push(pad(now.getHours()))
                break
            case 'MI':
                parts.push(pad(now.getMinutes()))
                break
            case 'SS':
                parts.push(pad(now.getSeconds()))
                break
            default:
                break
        }
    })
    const datePart = parts.join('')
    const seq = '1'.padStart(r.serialLength ?? 4, '0')
    return (r.codePrefix || '') + datePart + seq
}

function buildTimeFormat(segments: string[]) {
    const map: Record<string, string> = {
        'YYYY': 'yyyy',
        'YY': 'yy',
        'MM': 'MM',
        'DD': 'dd',
        'HH': 'HH',
        'MI': 'mm',
        'SS': 'ss'
    }
    // 定义时间单位的顺序（从大到小）
    const order: string[] = ['YYYY', 'YY', 'MM', 'DD', 'HH', 'MI', 'SS']

    // 按照从大到小的顺序排序
    const sorted = segments.sort((a, b) => {
        const indexA = order.indexOf(a)
        const indexB = order.indexOf(b)
        if (indexA === -1 && indexB === -1) return 0
        if (indexA === -1) return 1
        if (indexB === -1) return -1
        return indexA - indexB
    })

    return sorted.map(seg => map[seg] || seg).join('')
}

function getCurrentUserName() {
    const possibleKeys = [
        'username',
        'userName',
        'user_account',
        'userAccount',
        'realName',
        'nickName',
        'account',
        'currentUser'
    ]
    for (const key of possibleKeys) {
        const val = localStorage.getItem(key) || sessionStorage.getItem(key)
        if (val) return val
    }
    try {
        const info = localStorage.getItem('userInfo') || sessionStorage.getItem('userInfo')
        if (info) {
            const parsed = JSON.parse(info)
            const candidates = [parsed?.userName, parsed?.username, parsed?.name, parsed?.nickName]
            const hit = candidates.find(v => typeof v === 'string' && v.trim())
            if (hit) return hit
        }
    } catch { /* ignore */ }
    return '系统用户'
}

function formatDateTime(val?: string | Date) {
    if (!val) return '--'
    return moment(val).format('YYYY-MM-DD HH:mm:ss')
}

function resetQuery() {
    query.targetName = ''
    query.prefix = ''
    query.timeRule = ''
    query.operateTime = null
    loadData()
}

// 导出功能
function handleExport() {
    const params: any = {
        targetName: query.targetName || undefined,
        prefix: query.prefix || undefined,
        timeRule: query.timeRule || undefined
    }
    if (query.operateTime && query.operateTime.length === 2) {
        params.startTime = query.operateTime[0]
        params.endTime = query.operateTime[1]
    }

    const queryString = Object.entries(params)
        .filter(([_, v]) => v !== undefined)
        .map(([k, v]) => `${k}=${encodeURIComponent(String(v))}`)
        .join('&')

    const url = `/api/Number/ExportNumberingRules${queryString ? '?' + queryString : ''}`
    window.open(url, '_blank')
}

async function loadData() {
    loading.value = true
    try {
        const params: any = {
            targetName: query.targetName || undefined,
            prefix: query.prefix || undefined,
            timeRule: query.timeRule || undefined
        }
        if (query.operateTime && query.operateTime.length === 2) {
            params.startTime = query.operateTime[0]
            params.endTime = query.operateTime[1]
        }

        const res = await myaxios({
            url: '/api/Number/QueryNumberingRules',
            method: 'get',
            params
        })
        const body = res?.data
        if (body?.code !== 200) throw new Error(body?.message || '接口返回异常')
        const list = Array.isArray(body?.data) ? body.data : []
        rows.value = list
        updateTargetOptions(list)
    } catch (err) {
        console.error(err)
        ElMessage.error('加载失败')
    } finally {
        loading.value = false
    }
}

async function fetchDetail(ruleId: NumberRule['ruleId']) {
    if (!ruleId) return null
    try {
        const res = await myaxios({
            url: '/api/Number/GetNumberingRule',
            method: 'get',
            params: { ruleId }
        })
        return res?.data?.data || null
    } catch (err) {
        console.error(err)
        return null
    }
}

async function openEdit(row?: NumberRule) {
    if (row?.ruleId) {
        // 编辑时回填数据
        const detail = await fetchDetail(row.ruleId)
        if (detail) {
            Object.assign(form, { ...defaultForm, ...detail })
            // 回填时间规则：将 timeRule 字符串解析为数组
            // 支持多种格式：逗号分隔 "YYYY,MM,DD" 或直接字符串 "YYYYMMDD"
            const timeRuleStr = detail.timeRule || ''
            if (timeRuleStr) {
                let segments: string[] = []
                // 如果是逗号分隔的格式
                if (timeRuleStr.includes(',')) {
                    segments = timeRuleStr.split(',').filter(Boolean).map((s: string) => s.trim().toUpperCase())
                } else if (detail.timeFormat) {
                    // 如果 timeRule 为空但有 timeFormat，从 timeFormat 解析
                    const formatMap: Record<string, string> = {
                        'yyyy': 'YYYY', 'yy': 'YY', 'MM': 'MM', 'dd': 'DD',
                        'HH': 'HH', 'mm': 'MI', 'ss': 'SS'
                    }
                    const formatStr = (detail.timeFormat || '').toLowerCase()
                    let i = 0
                    while (i < formatStr.length) {
                        const sub4 = formatStr.substring(i, i + 4)
                        const sub2 = formatStr.substring(i, i + 2)
                        if (i + 4 <= formatStr.length && sub4 && formatMap[sub4]) {
                            segments.push(formatMap[sub4])
                            i += 4
                        } else if (i + 2 <= formatStr.length && sub2 && formatMap[sub2]) {
                            segments.push(formatMap[sub2])
                            i += 2
                        } else {
                            i++
                        }
                    }
                }
                // 使用 nextTick 确保视图更新
                await nextTick()
                timeSegments.value = segments
                form.timeRule = segments.join(',')
                console.log('回填时间规则 - detail.timeRule:', detail.timeRule, 'detail.timeFormat:', detail.timeFormat, '解析结果:', segments)
            } else {
                await nextTick()
                timeSegments.value = []
                form.timeRule = ''
            }
        }
    } else {
        // 新增时清空，不设置默认值
        Object.assign(form, { ...defaultForm })
        await nextTick()
        timeSegments.value = []
        form.timeRule = ''
        form.timeFormat = ''
        form.numberingExpression = ''
    }
    editVisible.value = true
}

function doSave() {
    // 先验证时间规则是否至少选择了一个
    if (timeSegments.value.length === 0) {
        ElMessage.warning('请至少选择一个时间规则')
        return
    }

    formRef.value?.validate(async (valid) => {
        if (!valid) return
        const payload: any = { ...form }

        // 按照从大到小的顺序排序时间规则并保存
        const order: string[] = ['YYYY', 'YY', 'MM', 'DD', 'HH', 'MI', 'SS']
        const sortedSegments = [...timeSegments.value].sort((a, b) => {
            const indexA = order.indexOf(a)
            const indexB = order.indexOf(b)
            if (indexA === -1 && indexB === -1) return 0
            if (indexA === -1) return 1
            if (indexB === -1) return -1
            return indexA - indexB
        })
        payload.timeRule = sortedSegments.join(',')

        // 删除分隔符字段，不再使用
        delete payload.separator
        const isNew = !payload.ruleId
        payload.timeFormat = buildTimeFormat(sortedSegments)
        payload.numberingExpression = buildPreview(payload)
        const currentUser = getCurrentUserName()
        payload.operator = payload.operator || currentUser
        if (isNew) {
            payload.creator = payload.creator || currentUser
            delete payload.updater
        } else {
            payload.updater = currentUser
        }
        const url = isNew ? '/api/Number/CreateNumberingRule' : '/api/Number/UpdateNumberingRule'
        const method = isNew ? 'post' : 'put'
        try {
            const config: any = { url, method, data: payload }
            if (isNew) {
                config.params = { creator: payload.creator }
            } else {
                config.params = { updater: payload.updater }
            }
            const res = await myaxios(config)
            if (res?.data?.code === 200) {
                ElMessage.success('保存成功')
                editVisible.value = false
                loadData()
            } else {
                throw new Error(res?.data?.message || '保存失败')
            }
        } catch (err: any) {
            ElMessage.error(err?.message || '保存失败')
        }
    })
}

async function doRemove(row: NumberRule) {
    if (!row.ruleId) return
    try {
        await ElMessageBox.confirm('删除后不可恢复，确认继续？', '提示', { type: 'warning' })
        const res = await myaxios({
            url: '/api/Number/DeleteNumberingRule',
            method: 'delete',
            params: {
                ruleId: row.ruleId,
                deleter: getCurrentUserName()
            }
        })
        if (res?.data?.code === 200) {
            ElMessage.success('删除成功')
            loadData()
        } else {
            throw new Error(res?.data?.message || '删除失败')
        }
    } catch (err: any) {
        if (err === 'cancel') return
        ElMessage.error(err?.message || '删除失败')
    }
}

onMounted(() => {
    loadData()
})

function updateTargetOptions(list: NumberRule[]) {
    const dynamic = list
        .map(item => item.targetName)
        .filter((name): name is string => !!name && typeof name === 'string')
    const merged = Array.from(new Set([...dynamic]))
    targetOptions.value = merged
}
</script>

<style scoped>
.nr-page {
    padding: 16px;
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.search-card,
.action-card,
.table-card {
    margin-bottom: 0;
}

.search-form {
    margin-top: 10px;
}

.search-form .el-form-item {
    margin-bottom: 0;
}

.action-card {
    padding: 12px 16px;
}

.action-card .el-button {
    margin-right: 10px;
}

.drawer-footer {
    display: flex;
    justify-content: flex-end;
    gap: 10px;
}
</style>
